﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;

namespace CXW.Core.Util
{
    public class ConfigManager
    {
        const string PREV = "TableColumn.";//按一定规则命名的文本资源值。       
        const string PREV_GLOBAL = "Global.";
        private const string DEFAULTWIDTH = "DefaultColumnWidth";
        private static Dictionary<string, Hashtable> dicCache = new Dictionary<string, Hashtable>(StringComparer.OrdinalIgnoreCase);
        private static Dictionary<string, Dictionary<string, string>> dicPath = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
        public static ViewData GetViewDataQuery(string sPath, string key)
        {
            return GetViewDataQuery(sPath).ArrayViewData.FirstOrDefault(item => item.DataKey == key);
        }
        public static ViewTemplate GetViewTemplate(string sName)
        {
            ViewTemplate tpl = GetXmlSerializer<ViewTemplate>(sName, "*.xml");
            if (tpl != null && tpl.Columns != null)
            {
                bool BehaviorEditable = false;
                foreach (ViewColumn column in tpl.Columns)
                {
                    if (string.IsNullOrEmpty(column.Editable))
                        column.AllowEdit = tpl.Editable;
                    else
                        column.AllowEdit = bool.Parse(column.Editable);

                    if (column.AllowEdit) { BehaviorEditable = true; }

                    if (column.Width == 120)//默认80
                    {
                        ViewColumn GloCol = ColumnsWidth.FirstOrDefault(item => item.DataField.Equals(column.DataField, StringComparison.CurrentCultureIgnoreCase));
                        if (GloCol != null) { column.Width = GloCol.Width; }
                    }
                    string str = PREV + column.DataField;
                    string zh = ResourceService.GetString(str);
                    if (zh.Equals(str))
                    {
                        string CtrlNameGlobal = PREV_GLOBAL + column.DataField;
                        zh = ResourceService.GetString(CtrlNameGlobal);
                        if (zh.Equals(CtrlNameGlobal))
                            zh = str;
                    }

                    if (!str.Equals(zh)) { column.Caption = zh; }
                }
                //解决grdView.OptionsBehavior.Editable=false时，
                //即使某列AllowEdit=true，仍然不能编辑的问题。
                //只要有一列是可编辑的，将Editable重置成true。
                tpl.Editable = BehaviorEditable;
            }
            return tpl;
        }

        static ViewColumn[] GetDefaultWidth()
        {
            ViewTemplate vt = GetXmlSerializer<ViewTemplate>(DEFAULTWIDTH, "*.xml");
            if (vt == null) { return null; }
            else { return vt.Columns; }
        }

        static ViewColumn[] _colsWidth;
        static ViewColumn[] ColumnsWidth
        {
            get
            {
                return _colsWidth == null ? _colsWidth = GetDefaultWidth() : _colsWidth;
            }
        }

        public static ViewDatas GetViewDataQuery(string sName)
        {
            return GetXmlSerializer<ViewDatas>(sName, "*.cfg");
        }

        static string GetPath(string key, string sName, string filter)
        {
            if (!dicPath.ContainsKey(key))
                dicPath.Add(key, new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase));

            if (dicPath[key].Count == 0)
            {
                string addInDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AddIns");
                string[] cfg = Directory.GetFiles(addInDir, filter, SearchOption.AllDirectories);
                foreach (string s in cfg)
                {
                    string fname = Path.GetFileNameWithoutExtension(s);
                    if (!dicPath[key].ContainsKey(fname))
                        dicPath[key].Add(fname, s);
                    else
                        LoggingService.Error(string.Format("[{0}]{1}文件名已存在", fname, filter));
                }
            }
            return dicPath[key].ContainsKey(sName) ? dicPath[key][sName] : string.Empty;
        }

        static T GetXmlSerializer<T>(string sName, string filter) where T : class
        {
            string key = typeof(T).FullName;

            if (!dicCache.ContainsKey(key))
                dicCache.Add(key, Hashtable.Synchronized(new Hashtable()));

            T oSeria = dicCache[key][sName] as T;

            if (oSeria == null)
            {
                string sPath = GetPath(key, sName, filter);
                if (string.IsNullOrEmpty(sPath))
                {
                    string str = string.Format("配置文件不存在:{0}{1}", sName, filter);
                    MessageService.ShowMessage(str);
                    return null;
                }
                XmlSerializer oXmlSerializer = new XmlSerializer(typeof(T));
                XmlTextReader oXmlReader = new XmlTextReader(sPath);

                try
                {
                    oSeria = (T)oXmlSerializer.Deserialize(oXmlReader);
                }
                finally
                {
                    oXmlReader.Close();
                }
                if (!dicCache[key].ContainsKey(sName))
                    dicCache[key].Add(sName, oSeria);
                else
                    dicCache[key][sName] = oSeria;
            }
            return oSeria;
        }
    }
}
